// Html2Txt project main.go
package main

import (
	"fmt"
	"io"
	"net/http"
	uri "net/url"
	"os"
	"sync"
	"time"
)

var g_args Args

type fileSave struct {
	WriteFile io.Writer
	Index     int
	Mutex     sync.Mutex
}

var g_save fileSave

func main() {
	if !g_args.Init() {
		os.Exit(2)
	}

	var config Config
	config.Load("config.json")

	// 根据网址确定所使用的配置
	LogPrintln(0, "解析网址: ", g_args.URL)
	url, uerr := uri.Parse(g_args.URL)
	if uerr != nil {
		LogPrintln(0, "网址解析失败: ", uerr)
		return
	}
	configIndex := 0
	for ; configIndex < len(config.Items); configIndex++ {
		if config.Items[configIndex].Domain == url.Host {
			break
		}
	}
	if configIndex >= len(config.Items) {
		LogPrintf(0, "未找到当前域名 [%s] 对应的配置文件\n", url.Host)
		return
	}

	// 显示配置信息
	LogPrintln(0, "选用配置: ", config.Get(configIndex).SiteName)
	LogPrintln(0, "域名: ", config.Get(configIndex).Domain)
	LogPrintln(0, "字符编码: ", config.Get(configIndex).Code)

	if (g_args.Dl || g_args.Dp) && g_args.Log < 3 {
		g_args.Log = 3
	}

	// 测试单页内容
	if g_args.Dp {
		inner, ok := DownloadPage("测试章节", g_args.URL, config.Get(configIndex))
		if ok {
			LogPrintln(0, inner)
		}
		return
	}

	var list weblist
	if !list.ParseIndex(config.Get(configIndex)) {
		return
	}

	if g_args.Dl {
		return
	}

	// 创建目标储存文件
	var fWrite *os.File
	if g_args.Out == "" {
		g_save.WriteFile = os.Stdout
	} else {
		var err error
		fWrite, err = os.Create(g_args.Out)
		g_save.WriteFile = fWrite
		if err != nil {
			LogPrintf(0, "文件 %s 创建失败: %v\n", g_args.Out, err)
			return
		}
	}

	// 下载超时时间
	http.DefaultClient.Timeout = time.Second * time.Duration(g_args.Timeout)

	// 执行下载
	dchan := make(chan int, g_args.Job)
	g_save.Index = 0
	for i := 0; i < g_args.Job; i++ {
		go downloadThread(&list, config.Get(configIndex), dchan)
	}

	for i := 0; i < g_args.Job; i++ {
		ch := <-dchan
		LogPrintln(9, "完成线程: ", ch)
	}
	if fWrite != nil {
		fWrite.Close()
	}
}

// 在线程中下载 web 内容
func downloadThread(list *weblist, config SiteItem, ch chan int) {
	var page string
	var index int
	var ok bool

	for {
		index, page, ok = list.DownloadPageMutex(config)
		if index < 0 || !ok {
			ch <- index
			return
		}

		for {
			if index <= g_save.Index {
				g_save.Mutex.Lock()
				g_save.Index++
				fmt.Fprint(g_save.WriteFile, page)
				g_save.Mutex.Unlock()
				break
			}

			time.Sleep(time.Millisecond * 10)
		}
	}
}
